package kr.pe.johnkim.checkmileage.mobile.rest.controller;

import kr.pe.johnkim.checkmileage.mobile.domain.CheckMileageCertification;
import kr.pe.johnkim.checkmileage.mobile.domain.CheckMileageMember;
import kr.pe.johnkim.checkmileage.mobile.rest.service.CheckMileageMemberService;
import kr.pe.johnkim.checkmileage.mobile.util.CheckMileageCommon;
import org.codehaus.jettison.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * Check Mileage 사용자 관련 Controller 클래스 이다.
 * 
 * @author : johnkim <cale9797@gmail.com / Bettersoft, Inc.>
 * @Date : 12. 7. 24
 */

@Controller
@Path("/checkMileageMemberController")
public class CheckMileageMemberController {

    // SLF4J Logging
	private Logger logger = LoggerFactory.getLogger(CheckMileageMemberController.class);

    @Autowired
    private CheckMileageMemberService checkMileageMemberService = null;

    @Autowired
    private CheckMileageCommon checkMileageCommon = null;

    /**
     * 아이디로 기존에 등록된 사용자가 있는지 확인 한다.
     *
     * @param is
     * @return
     * @throws Exception
     */
    @POST
    @Path("/selectMemberExist")
    @Consumes({"application/json", "application/xml"})
    @Produces({"application/json", "application/xml"})
    public CheckMileageMember selectMemberExist(InputStream is) throws Exception {
        logger.info("registerMember");

        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = br.readLine();

        logger.info("line : {}", line);

        JSONObject jsonMember = new JSONObject(line);
        JSONObject jsonMember2 = jsonMember.getJSONObject("checkMileageMember");

        CheckMileageMember parameterMember = new CheckMileageMember();

        parameterMember.setCheckMileageId(jsonMember2.getString("checkMileageId"));
        parameterMember.setActivateYn(jsonMember2.getString("activateYn"));

        return checkMileageMemberService.selectMemberExist(parameterMember);
    }

    /**
     * 사용자를 등록 한다.
     *
     * @param is
     * @return
     * @throws Exception
     */
    @POST
    @Path("/registerMember")
    @Consumes({"application/json", "application/xml"})
    @Produces({"application/json", "application/xml"})
    public CheckMileageMember registerMember(InputStream is) throws Exception {
        logger.info("registerMember");

        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = br.readLine();

        logger.info("line : {}", line);

        JSONObject jsonMember = new JSONObject(line);
        JSONObject jsonMember2 = jsonMember.getJSONObject("checkMileageMember");

        CheckMileageMember parameterMember = new CheckMileageMember();

        parameterMember.setCheckMileageId(jsonMember2.getString("checkMileageId"));
        parameterMember.setPassword(jsonMember2.getString("password"));
        parameterMember.setPhoneNumber(jsonMember2.getString("phoneNumber"));
        parameterMember.setEmail(jsonMember2.getString("email"));
        parameterMember.setBirthday(jsonMember2.getString("birthday"));
        parameterMember.setGender(jsonMember2.getString("gender"));
        parameterMember.setCountryCode(jsonMember2.getString("countryCode"));
        parameterMember.setLanguageCode(jsonMember2.getString("languageCode"));
        parameterMember.setLatitude(jsonMember2.getString("latitude"));
        parameterMember.setLongitude(jsonMember2.getString("longitude"));
        parameterMember.setDeviceType(jsonMember2.getString("deviceType"));
        parameterMember.setRegistrationId(jsonMember2.getString("registrationId"));
        parameterMember.setReceiveNotificationYn(jsonMember2.getString("receiveNotificationYn"));
        parameterMember.setActivateYn(jsonMember2.getString("activateYn"));
        parameterMember.setModifyDate(jsonMember2.getString("modifyDate"));
        parameterMember.setRegisterDate(jsonMember2.getString("registerDate"));

        CheckMileageMember resultMember = new CheckMileageMember();

        try {
            checkMileageMemberService.registerMember(parameterMember);
            resultMember.setResult("SUCCESS");
        } catch (Exception e) {
            resultMember.setResult("FAIL");
            logger.error("Fail to register member.");
        }

        return resultMember;
    }

    /**
     * 사용자 정보를 가져 온다.
     * 
     * @param is
     * @return
     * @throws Exception
     */
    @POST
    @Path("/selectMemberInformation")
    @Consumes({"application/json", "application/xml"})
    @Produces({"application/json", "application/xml"})
    public CheckMileageMember selectMemberInformation(InputStream is) throws Exception {
        logger.info("selectMemberInformation");

        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = br.readLine();

        logger.info("line : {}", line);

        JSONObject jsonMember = new JSONObject(line);
        JSONObject jsonMember2 = jsonMember.getJSONObject("checkMileageMember");

        CheckMileageMember parameterMember = new CheckMileageMember();

        parameterMember.setCheckMileageId(jsonMember2.getString("checkMileageId"));
        parameterMember.setActivateYn(jsonMember2.getString("activateYn"));

        return checkMileageMemberService.selectMemberInformation(parameterMember);
    }

    /**
     * 사용자 정보를 수정 한다.
     * 
     * @param is
     * @return
     * @throws Exception
     */
    @POST
    @Path("/updateMemberInformation")
    @Consumes({"application/json", "application/xml"})
    @Produces({"application/json", "application/xml"})
    public CheckMileageMember updateMemberInformation(InputStream is) throws Exception {
        logger.info("updateMemberInformation");

        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = br.readLine();

        logger.info("line : {}", line);

        JSONObject jsonMember = new JSONObject(line);
        JSONObject jsonMember2 = jsonMember.getJSONObject("checkMileageMember");

        CheckMileageMember parameterMember = new CheckMileageMember();

        parameterMember.setCheckMileageId(jsonMember2.getString("checkMileageId"));
        parameterMember.setPassword(jsonMember2.getString("password"));
        parameterMember.setPhoneNumber(jsonMember2.getString("phoneNumber"));
        parameterMember.setEmail(jsonMember2.getString("email"));
        parameterMember.setBirthday(jsonMember2.getString("birthday"));
        parameterMember.setGender(jsonMember2.getString("gender"));
        parameterMember.setCountryCode(jsonMember2.getString("countryCode"));
        parameterMember.setLanguageCode(jsonMember2.getString("languageCode"));
        parameterMember.setLatitude(jsonMember2.getString("latitude"));
        parameterMember.setLongitude(jsonMember2.getString("longitude"));
        parameterMember.setDeviceType(jsonMember2.getString("deviceType"));
        parameterMember.setRegistrationId(jsonMember2.getString("registrationId"));
        parameterMember.setReceiveNotificationYn(jsonMember2.getString("receiveNotificationYn"));
        parameterMember.setActivateYn(jsonMember2.getString("activateYn"));
        parameterMember.setModifyDate(jsonMember2.getString("modifyDate"));

        logger.info("checkMileageId        : {}", parameterMember.getCheckMileageId());
        logger.info("password              : {}", parameterMember.getPassword());
        logger.info("phoneNumber           : {}", parameterMember.getPhoneNumber());
        logger.info("email                 : {}", parameterMember.getEmail());
        logger.info("birthday              : {}", parameterMember.getBirthday());
        logger.info("gender                : {}", parameterMember.getGender());
        logger.info("countryCode           : {}", parameterMember.getCountryCode());
        logger.info("languageCode          : {}", parameterMember.getLanguageCode());
        logger.info("latitude              : {}", parameterMember.getLatitude());
        logger.info("longitude             : {}", parameterMember.getLongitude());
        logger.info("deviceType            : {}", parameterMember.getDeviceType());
        logger.info("registrationId        : {}", parameterMember.getRegistrationId());
        logger.info("receiveNotificationYn : {}", parameterMember.getReceiveNotificationYn());
        logger.info("activateYn            : {}", parameterMember.getActivateYn());
        logger.info("modifyDate            : {}", parameterMember.getModifyDate());

        CheckMileageMember resultMember = new CheckMileageMember();

        try {
            checkMileageMemberService.updateMemberInformation(parameterMember);
            resultMember.setResult("SUCCESS");
        } catch (Exception e) {
            resultMember.setResult("FAIL");
            logger.error("Fail to update member information.");
        }

        return resultMember;
    }

    /**
     * 사용자를 비활성화 한다.
     * 
     * @param is
     * @return
     * @throws Exception
     */
    @POST
    @Path("/updateDeactivateMember")
    @Consumes({"application/json", "application/xml"})
    @Produces({"application/json", "application/xml"})
    public CheckMileageMember updateDeactivateMember(InputStream is) throws Exception {
        logger.info("updateDeactivateMember");

        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = br.readLine();

        logger.info("line : {}", line);

        JSONObject jsonMember = new JSONObject(line);
        JSONObject jsonMember2 = jsonMember.getJSONObject("checkMileageMember");

        CheckMileageMember parameterMember = new CheckMileageMember();

        parameterMember.setCheckMileageId(jsonMember2.getString("checkMileageId"));
        parameterMember.setActivateYn(jsonMember2.getString("activateYn"));
        parameterMember.setModifyDate(jsonMember2.getString("modifyDate"));

        CheckMileageMember resultMember = new CheckMileageMember();

        try {
            checkMileageMemberService.updateDeactivateMember(parameterMember);
            resultMember.setResult("SUCCESS");
        } catch (Exception e) {
            resultMember.setResult("FAIL");
            logger.error("Fail to update deactivate member.");
        }

        return resultMember;
    }

    /**
     * 사용자의 Google GCM Registration Id / APNS Device Token 을 수정 한다.
     * 
     * @param is
     * @return
     * @throws Exception
     */
    @POST
    @Path("/updateRegistrationId")
    @Consumes({"application/json", "application/xml"})
    @Produces({"application/json", "application/xml"})
    public CheckMileageMember updateRegistrationId(InputStream is) throws Exception {
        logger.info("updateRegistrationId");

        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = br.readLine();

        logger.info("line : {}", line);

        JSONObject jsonMember = new JSONObject(line);
        JSONObject jsonMember2 = jsonMember.getJSONObject("checkMileageMember");

        CheckMileageMember parameterMember = new CheckMileageMember();

        parameterMember.setCheckMileageId(jsonMember2.getString("checkMileageId"));
        parameterMember.setRegistrationId(jsonMember2.getString("registrationId"));
        parameterMember.setActivateYn(jsonMember2.getString("activateYn"));
        parameterMember.setModifyDate(jsonMember2.getString("modifyDate"));

        CheckMileageMember resultMember = new CheckMileageMember();

        try {
            checkMileageMemberService.updateRegistrationId(parameterMember);
            resultMember.setResult("SUCCESS");
        } catch (Exception e) {
            resultMember.setResult("FAIL");
            logger.error("Fail to update registration id.");
        }

        return resultMember;
    }

    /**
     * Push Notification 수신 여부를 수정 한다.
     *
     * @param is
     * @return
     * @throws Exception
     */
    @POST
    @Path("/updateReceiveNotification")
    @Consumes({"application/json", "application/xml"})
    @Produces({"application/json", "application/xml"})
    public  CheckMileageMember updateReceiveNotification(InputStream is) throws Exception {
        logger.info("updateRegistrationId");

        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = br.readLine();

        logger.info("line : {}", line);

        JSONObject jsonMember = new JSONObject(line);
        JSONObject jsonMember2 = jsonMember.getJSONObject("checkMileageMember");

        CheckMileageMember parameterMember = new CheckMileageMember();

        parameterMember.setCheckMileageId(jsonMember2.getString("checkMileageId"));
        parameterMember.setReceiveNotificationYn(jsonMember2.getString("receiveNotificationYn"));
        parameterMember.setActivateYn(jsonMember2.getString("activateYn"));
        parameterMember.setModifyDate(jsonMember2.getString("modifyDate"));

        CheckMileageMember resultMember = new CheckMileageMember();

        try {
            checkMileageMemberService.updateReceiveNotification(parameterMember);
            resultMember.setResult("SUCCESS");
        } catch (Exception e) {
            resultMember.setResult("FAIL");
            logger.error("Fail to update receive notification.");
        }

        return resultMember;
    }

    /**
     * 사용자의 위치 정보를 수정 한다.
     *
     * @param is
     * @return
     * @throws Exception
     */
    @POST
    @Path("/updateMemberLocation")
    @Consumes({"application/json", "application/xml"})
    @Produces({"application/json", "application/xml"})
    public CheckMileageMember updateMemberLocation(InputStream is) throws Exception {
        logger.info("updateRegistrationId");

        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = br.readLine();

        logger.info("line : {}", line);

        JSONObject jsonMember = new JSONObject(line);
        JSONObject jsonMember2 = jsonMember.getJSONObject("checkMileageMember");

        CheckMileageMember parameterMember = new CheckMileageMember();

        parameterMember.setCheckMileageId(jsonMember2.getString("checkMileageId"));
        parameterMember.setLatitude(jsonMember2.getString("latitude"));
        parameterMember.setLongitude(jsonMember2.getString("longitude"));
        parameterMember.setActivateYn(jsonMember2.getString("activateYn"));
        parameterMember.setModifyDate(jsonMember2.getString("modifyDate"));

        CheckMileageMember resultMember = new CheckMileageMember();

        try {
            checkMileageMemberService.updateMemberLocation(parameterMember);
            resultMember.setResult("SUCCESS");
        } catch (Exception e) {
            resultMember.setResult("FAIL");
            logger.error("Fail to update member location.");
        }

        return resultMember;
    }

    /**
     * 전화번호로 기존 사용자가 있는지 확인 한다.
     * 
     * @param is
     * @return
     * @throws Exception
     */
    @POST
    @Path("/selectMemberExistByPhoneNumber")
    @Consumes({"application/json", "application/xml"})
    @Produces({"application/json", "application/xml"})
    public CheckMileageMember selectMemberExistByPhoneNumber(InputStream is) throws Exception {
        logger.info("selectMemberExistByPhoneNumber");

        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = br.readLine();

        logger.info("line : {}", line);

        JSONObject jsonMember = new JSONObject(line);
        JSONObject jsonMember2 = jsonMember.getJSONObject("checkMileageMember");

        CheckMileageMember parameterMember = new CheckMileageMember();

        parameterMember.setPhoneNumber(jsonMember2.getString("phoneNumber"));
        parameterMember.setActivateYn(jsonMember2.getString("activateYn"));

        return checkMileageMemberService.selectMemberExistByPhoneNumber(parameterMember);
    }

    /**
     * 전화번호로 기존 사용자 정보를 가져 온다.
     *
     * 인증 번호 요청 버튼을 터치하면 기존 사용자 정보가 있는지 확인한 뒤 넘겨 주는데,
     * 받은 client 에서는 QR 코드가 있으면 메인화면으로, 없으면 인증화면으로 이동 한다.
     *
     * @param is
     * @return
     * @throws Exception
     */
    @POST
    @Path("/selectMemberInformationByPhoneNumber")
    @Consumes({"application/json", "application/xml"})
    @Produces({"application/json", "application/xml"})
    public CheckMileageMember selectMemberInformationByPhoneNumber(InputStream is) throws Exception {
        logger.info("selectMemberInformationByPhoneNumber");

        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = br.readLine();

        logger.info("line : {}", line);

        JSONObject jsonMember = new JSONObject(line);
        JSONObject jsonMember2 = jsonMember.getJSONObject("checkMileageMember");

        CheckMileageMember parameterMember = new CheckMileageMember();

        parameterMember.setPhoneNumber(jsonMember2.getString("phoneNumber"));
        parameterMember.setActivateYn(jsonMember2.getString("activateYn"));

        CheckMileageMember resultMember = new CheckMileageMember();

        /**
         * 기존 사용자 정보가 존재하면 사용자 정보를 client 로 리턴하고 로직을 종료 한다.
         *
         * 기존 사용자 정보가 존재하지 않으면 빈값을 client 로 리턴하고
         * 인증번호를 생성한 다음 비교 테이블에 저장하고 SMS 발송한 뒤 로직을 종료 한다.
         *
         * client 에서는 받은 사용자정보의 유무에 따라서 메인화면으로 갈 것인지 인증 화면으로 갈 것인지 판단 한다.
         */
        if(("1").equals(checkMileageMemberService.selectMemberExistByPhoneNumber(parameterMember).getTotalCount())) {
            logger.info("already member.");

            resultMember = checkMileageMemberService.selectMemberInformationByPhoneNumber(parameterMember);
        } else {
            logger.info("not yet member.");

            resultMember.setCheckMileageId("");

            String certificationNumber = checkMileageCommon.getCertificationNumber();

            CheckMileageCertification parameterCertification = new CheckMileageCertification();

            parameterCertification.setPhoneNumber(jsonMember2.getString("phoneNumber"));
            parameterCertification.setCertificationNumber(certificationNumber);
            parameterCertification.setModifyDate(checkMileageCommon.getCurrentDate());
            parameterCertification.setRegisterDate(checkMileageCommon.getCurrentDate());

            logger.info("phoneNumber         : {}", parameterCertification.getPhoneNumber());
            logger.info("certificationNumber : {}", certificationNumber);
            logger.info("modifyDate          : {}", parameterCertification.getModifyDate());
            logger.info("registerDate        : {}", parameterCertification.getRegisterDate());

//            checkMileageCertificationService.registerCertificationNumber(parameterCertification);

            // 인증번호를 SMS 로 송신 한다.
        }

        return resultMember;
    }

    /**
     * Google GCM 테스트 메소드.
     * 
     * @param is
     * @throws Exception
     */
    @POST
    @Path("/testGCM")
    @Consumes({"application/json", "application/xml"})
    @Produces({"application/json", "application/xml"})
    public void testGCM(InputStream is) throws Exception {
        logger.info("testGCM");

        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = br.readLine();

        logger.info("line : {}", line);

        JSONObject jsonMember = new JSONObject(line);
        JSONObject jsonMember2 = jsonMember.getJSONObject("checkMileageMember");

        if((jsonMember2.getString("registrationId") != null) && (!("").equals(jsonMember2.getString("registrationId")))) {
            checkMileageCommon.sendASMessage(jsonMember2.getString("registrationId"), "Check Mileage 로 부터 새로운 메시지가 도착했습니다.");
        } else {
            logger.info("registrationId is not available!");
        }
    }
}
